<?php
// +----------------------------------------------------------------------
// | XShop小程序商城
// +----------------------------------------------------------------------
// | Author: Peak Xin <xinyflove@gmail.com>
// +----------------------------------------------------------------------

namespace app\api\service;


use app\lib\enum\ScopeEnum;
use app\lib\exception\ForbiddenException;
use app\lib\exception\TokenException;
use think\Cache;
use think\Exception;
use think\Request;

class Token {

    /**
     * 生成Token
     * @return string
     */
    public static function generateToken()
    {
        // 32个字符组成一组随机字符串
        $randChars = getRandChars(32);
        // 用三组字符串，进行md5加密
        $timestamp = $_SERVER['REQUEST_TIME_FLOAT'];
        //salt盐
        $salt = config('secure.token_salt');
        
        return md5($randChars.$timestamp.$salt);
    }

    /**
     * 获取当前token值
     * @param $key
     * @return mixed
     * @throws Exception
     * @throws TokenException
     */
    public static function getCurrentTokenVar($key)
    {
        $token = Request::instance()->header('token');
        $vars = Cache::get($token);
        if(!$vars) throw new TokenException();
        if(!is_array($vars)) $vars = json_decode($vars, true);
        if(!array_key_exists($key, $vars))
        {
            throw new Exception('尝试获取的Token变量不存在');
        }
        return $vars[$key];
    }

    /**
     * 获取当前uid
     * @return mixed
     * @throws Exception
     * @throws TokenException
     */
    public static function getCurrentUid()
    {
        $uid = self::getCurrentTokenVar('uid');
        return $uid;
    }

    /**
     * 需要基础权限
     * @return bool
     * @throws Exception
     * @throws ForbiddenException
     * @throws TokenException
     */
    public static function needPrimaryScope()
    {
        $scope = self::getCurrentTokenVar('scope');
        if($scope)
        {
            if($scope >= ScopeEnum::User) return true;
            throw new ForbiddenException();
        }
        throw new TokenException();
    }

    /**
     * 需要User权限
     * @return bool
     * @throws ForbiddenException
     * @throws TokenException
     */
    public static function needExclusiveScope()
    {
        $scope = self::getCurrentTokenVar('scope');
        if($scope)
        {
            if($scope == ScopeEnum::User) return true;
            throw new ForbiddenException();
        }
        throw new TokenException();
    }

    /**
     * 检查UID
     * @param $checkedUID
     * @return bool
     * @throws Exception
     */
    public static function isValidOperate($checkedUID)
    {
        if(!$checkedUID)
        {
            throw new Exception('检查UID时必须传入一个被检查的UID');
        }
        
        $currentOperateUID = self::getCurrentUid();
        if($currentOperateUID == $checkedUID)
        {
            return true;
        }
        return false;
    }

    /**
     * 验证Token是否有效
     * @param $token
     * @return bool
     */
    public static function verifyToken($token)
    {
        $exist = Cache::get($token);
        if ($exist)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}